#coding=utf8
from utils.jsonUtils import obj_to_str
from ws_setting import core_logger, CUSTOM_OBJ_SESSION_ID_NAME

class Response():
    def __init__(self):
        self.async = True

    def handle(self, current, to_sessions, data=None):
        pass



class Text(Response):
    def __init__(self, data="", to=None):
        Response.__init__(self)
        self.data = data
        self.to = to

    def handle(self, current, to_sessions, data=None):
        core_logger.debug("########### in textResponse handle method ##########")
        """
            向该session发送消息，委托acceptor来实际处理
        """
        if data:
            for client in to_sessions:
                if client== current:
                    current.send_data(data)
                    core_logger.info("send data = {} to client = {}".format(data, getattr(current, CUSTOM_OBJ_SESSION_ID_NAME)))
                else:
                    client.send_data(data)
                    core_logger.info("send data = {} to client = {}".format(data, getattr(client, CUSTOM_OBJ_SESSION_ID_NAME)))

            if to_sessions is None:
                current.send_data(data)
                core_logger.error("send to myself to sessions is {}".format(to_sessions))
        else:
            core_logger.warn("no data to send")


class Stop(Response):
    def __init__(self, to=None):
        Response.__init__(self)
        self.to = to
        self.async = False

    def handle(self, current, to_sessions, data=None):
        core_logger.debug("########### in stopResponse handle method ##########")
        # just mark session will be closed
        for to in to_sessions:
            core_logger.debug("nodify session [{}] to close".format(getattr(to, CUSTOM_OBJ_SESSION_ID_NAME)))
            to.closed = True

        if not to_sessions:
            core_logger.debug("current session [{}] will close".format(getattr(current, CUSTOM_OBJ_SESSION_ID_NAME)))
            current.closed = True


class Custom(Response):
    def __init__(self, executor, to=None, async = True, **kargs):
        """
            executor : actually execute function
            to       : send message to specified session if to is not None
            async    : async to execute
 
        """
        Response.__init__(self)
        self.executor = executor
        self.to = to
        self.kargs = kargs
        self.async = async
        
    def handle(self, current, to_sessions, data=None):
        core_logger.debug("########### in customResponse handle method ##########")
        self.executor(current, to_sessions, data, **self.kargs)
        
"""
class Channel(Response):
    def __init__(self, channel, clean = None, to = None, handler = Text, length = 1024, **append):
        Response.__init__(self)
        self.channel = channel
        self.clean = clean
        self.append = append

        if not type(handler) == type(Response):
            raise RuntimeError("handler must be a type of Response not instance")

        if not issubclass(handler, Response) and not hasattr(handler, "__call__"):
            raise RuntimeError("handler must be instance of Response or subclass, or function")

        if handler == Channel:
            raise RuntimeError("not support Channel for handler")
            
        self.handler = handler 
        self.length = length
        self.to = to

    def handle(self, current, to_sessions, data=None):
        core_logger.debug("########### in channelResponse handle method ##########")
        handle = self.handler().handle if issubclass(self.handler, Response) else self.handler
        default_handlers = {"text": Text().handle, "stop": Stop().handle}
        args = [current, to_sessions]
        def get_result():
            while True:
                res = self.channel.recv(self.length)
                if res:
                    yield res
                else:
                    #args.append(None)
                    #handle(*args, **default_handlers)
                    break

        for res in get_result():
            if self.append:
                self.append["result"] = res
                args.append(self.append)
            else:
                args.append(res)

            if issubclass(self.handler, Response):
                handle(*args)
            else:
                handle(*args, **default_handlers)

        if self.clean:
            self.clean()

"""
class WsObject(object):
    '''

    '''
    def __init__(self, request):
        self._sid = request.attr(CUSTOM_OBJ_SESSION_ID_NAME)

    def __eq__(self, obj):
        if hasattr(obj, CUSTOM_OBJ_SESSION_ID_NAME) and hasattr(self, CUSTOM_OBJ_SESSION_ID_NAME):
            return getattr(self, CUSTOM_OBJ_SESSION_ID_NAME) == getattr(obj, CUSTOM_OBJ_SESSION_ID_NAME)
        return False

    def __hash__(self):
        return hash(getattr(self, CUSTOM_OBJ_SESSION_ID_NAME))

    def get_session_id(self):
        return self._sid
